home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 19 / CU Amiga Magazine's Super CD-ROM 19 (1998)(EMAP Images)(GB)[!][issue 1998-02].iso / CUCD / Online / NNTPd / server / msgid.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-11-17  |  4.7 KB  |  217 lines

  1. /* msgid -- message ID test
  2.  * vix 13feb91 [negative caching]
  3.  * vix 24may90 [written]
  4.  *
  5.  * with mods ken@sdd.hp.com 01jul90
  6.  *
  7.  * $Id: msgid.c,v 1.3 1994/11/17 16:40:42 sob Exp sob $
  8.  */
  9.  
  10. #include <stdio.h>
  11. #include <ctype.h>
  12. #include <sys/types.h>
  13. #include <sys/time.h>
  14. #ifdef hpux
  15. #include <sys/param.h>
  16. /*#include <libBSD.h> not in HPUX 9*/
  17. #endif
  18. #include <sys/socket.h>
  19. #include <sys/un.h>
  20. #include <syslog.h>
  21. #define NEEDMSGS
  22. #include "msgid.h"
  23. #include "../conf.h"
  24.  
  25. #ifdef MSGID
  26.  
  27. #ifdef WANT_MAIN
  28. char hostname[BUFSIZ];
  29. #else
  30. extern char hostname[];
  31. #endif
  32.  
  33. #define SERVERTIMEOUT    30
  34.  
  35. static int s = -1;
  36. static int read_answer();
  37.  
  38. /*
  39.  * Protocol:
  40.  *    Return value as used here is from the server to us.  Note that this
  41.  *    may not be the same as the return value from msgid().
  42.  *
  43.  *    3 message types:
  44.  *        MCANCEL: Delete an id from the holding queues.  Return value
  45.  *                 is non-zero for failure.
  46.  *        MADD:    Check for dup and add as needed.  Return value is 
  47.  *                 non-zero for dup.
  48.  *        MHOST:   Used to inform the server who is on the other end of this 
  49.  *                 nntpd.  Return value is non-zero for failure.  Used only
  50.  *                 in msgid_init().
  51.  */
  52.  
  53.  
  54. /* 
  55.  * returns: 0 for ok, 1 for failure
  56.  */
  57. msgid_init()
  58. {
  59.     char buf[300];
  60.     struct sockaddr_un n;
  61.     static dead_server_count = 0;
  62.  
  63.     s = socket(PF_UNIX, SOCK_STREAM, 0);
  64.     if (s < 0) {
  65.     syslog(LOG_ERR, "msgid: can't get socket: %m");
  66.     return(1);
  67.     }
  68.  
  69.     n.sun_family = AF_UNIX;
  70.     (void) strcpy(n.sun_path, SOCKNAME);
  71.  
  72.     if (0 > connect(s, &n, strlen(n.sun_path) + sizeof n.sun_family)) {
  73.     close(s);
  74.     s = -1;
  75.     /* only syslog every 128 messages, so that dead msgidd doesn't
  76.      * lead to multi-megabyte syslog files (vix, 13feb91)
  77.      */
  78.     if (!(dead_server_count++ % 128)) {
  79.         syslog(LOG_ERR, "msgid: connect to %s: %m", SOCKNAME);
  80.     }
  81.     return(1);
  82.     }
  83.  
  84.     (void) strcpy(buf, msgs[MHOST]);
  85.     (void) strcat(buf, hostname);
  86.     if (write(s, buf, strlen(buf)) < 0) {
  87.     close(s);
  88.     s = -1;
  89.     syslog(LOG_ERR, "msgid: host message write: %m", SOCKNAME);
  90.     return(1);
  91.     }
  92.  
  93.     return(read_answer());
  94. }
  95.  
  96.  
  97. /* 
  98.  * returns: nonzero = duplicate, return value doesn't mean much for the
  99.  *          MADD or MOLD messages
  100.  */
  101. int
  102. msgid(id, mtype)
  103.     char *id;
  104.     int mtype;
  105. {
  106.     char *cp, buf[256], *rindex();
  107.  
  108.     if (s == -1 && msgid_init())
  109.     return(0);
  110.  
  111.     /*
  112.      * We need to do this just because gethistent does it
  113.      * "in place" so add vs old gets fried ...
  114.      *
  115.      * If running Bnews, converts "id" to lower case.
  116.      * If running Cnews, converts "id" per rfc822.
  117.      */
  118. #ifdef CNEWS
  119.     cp = rindex(id, '@');        /* look for @ in message id */
  120.     if (cp != NULL)
  121.     for(; *cp != '\0'; ++cp)
  122. #else
  123.     for (cp = id; *cp != '\0'; ++cp)
  124. #endif
  125.         if (isupper(*cp))
  126.         *cp = tolower(*cp);
  127.  
  128.     (void) strcpy(buf, msgs[mtype]);
  129.     (void) strcat(buf, id);
  130.     if (0 > write(s, buf, strlen(buf))) {
  131.     syslog(LOG_ERR, "msgid: write: %m");
  132.     close(s);
  133.     s = -1;
  134.     return(0);
  135.     }
  136.     return(read_answer()); 
  137. }
  138.  
  139.  
  140. static int
  141. read_answer()
  142. {
  143.     unsigned char c;
  144.     fd_set readfds;
  145.     struct timeval to;
  146.     int i;
  147.  
  148.     FD_ZERO(&readfds);
  149.     FD_SET(s, &readfds);
  150.     to.tv_sec = SERVERTIMEOUT;
  151.     to.tv_usec = 0;
  152.     if ((i = select(s+1, &readfds, NULL, NULL, &to)) < 0) {
  153.     syslog(LOG_ERR, "msgid: select: %m");
  154.     goto bad;
  155.     }
  156.     if (i == 0 || FD_ISSET(s, &readfds) == 0 || (i = read(s, &c, 1)) == 0) {
  157.     syslog(LOG_ERR, "msgid: read timeout");
  158.     goto bad;
  159.     }
  160.     if (i < 0) {
  161.     syslog(LOG_ERR, "msgid: read: %m");
  162.     goto bad;
  163.     }
  164.     if (c)
  165.     return(1);
  166.     return(0);
  167. bad:
  168.     close(s);
  169.     s = -1;
  170.     return 0;
  171. }
  172.  
  173. #ifdef WANT_MAIN
  174. main(argc, argv)
  175.     int argc;
  176.     char *argv[];
  177. {
  178.     register int n;
  179.     char buf[BUFSIZ], cmd[20], id[BUFSIZ];
  180.  
  181.     if (gethostname(hostname, BUFSIZ)) {
  182.     perror("hostname");
  183.     exit(1);
  184.     }
  185.     (void) printf("host: %s\n", hostname);
  186.  
  187.     if (argc != 1) {
  188.     (void) fprintf(stderr, "usage: %s\n", argv[0]);
  189.     exit(1);
  190.     }
  191.  
  192. #ifdef LOG_DAEMON
  193.     openlog("msgid-test", LOG_PID, LOG_DAEMON);
  194. #else
  195.     openlog("msgid-test", LOG_PID);
  196. #endif
  197.  
  198.     while (fputs("cmd msgid: ", stdout), fflush(stdout), fgets(buf, BUFSIZ, stdin))
  199.     if ((n = sscanf(buf, "%[^ \t]%*[ \t]%[^\n]", cmd, id)) == 2) {
  200.         if (strcmp(cmd, "cancel") == 0)
  201.         (void) printf("%s\n", (msgid(id, MCANCEL) ? "failed" : "ok"));
  202.         else if (strcmp(cmd, "add") == 0)
  203.         (void) printf("%d\n", msgid(id, MADD));
  204.         /* 
  205.         (void) printf("%sduplicate\n", 
  206.                   (msgid(id, MADD) ? "" : "not a "));
  207.         */
  208.         else if (strcmp(cmd, "old") == 0)
  209.         (void) printf("%s\n", (msgid(id, MOLD) ? "failed" : "ok"));
  210.         else
  211.         (void) printf("possible cmds are cancel, add, and old\n");
  212.     } else
  213.         (void) printf("[%d] possible cmds are cancel, add, and old\n", n);
  214. }
  215. #endif
  216. #endif /* MSGID */
  217.